<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <!--以当前最高版本的ie渲染-->
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  <title>知识图谱</title>
  <meta name="description" content="">
  <!-- shrink-to-fit=no;兼容ios9系统-->
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <style>
    html, body {
      width: 100%;
      height: 100vh;
      margin: 0;
      padding: 0;
    }

    html {
      background: rgba(0, 0, 0, 0.53) !important;
    }

    *,
    *::before,
    *::after {
      -webkit-box-sizing: border-box;
      box-sizing: border-box;
    }

    ol, ul {
      list-style: none;
      padding: 0;
    }


    body {
      overflow-x: hidden;
      overflow-y: auto;
      background: rgba(253, 255, 255, 1) !important;
      background-size: cover;
      background-repeat: no-repeat;
    }

    body {
      display: flex;
      flex-direction: column;
      min-height: 600px;
    }

    header {
      padding-top: 10px;
      width: 100%;
      height: 70px;
      text-align: center;
      color: rgba(253, 255, 255, 1);
      font-weight: bolder;
      position: relative;
      display: none;
    }


    header p {
      position: absolute;
      width: 100%;
      left: 0;
      top: 5px;
      font-size: 1.4em;
      height: 40px;
      margin: 0 auto;
      padding: 5px 0 5px 0;
      text-shadow: 0 1px rgba(122, 174, 195, 0.15), 0 1px rgba(122, 174, 195, 0.3),
      0 1px rgba(122, 174, 195, 0.45), 0 1px rgba(122, 174, 195, 0.65),
      0 1px rgba(122, 174, 195, 0.75), 2px 4px 5px rgba(122, 174, 195, 1);
      /* border: 1px solid #21A5CA;*/
      /*  clip-path: polygon(0% 0%, 100% 0%, 90% 100%, 10% 100%);*/
    }

    .title:hover {
      cursor: pointer;
      color: rgba(255, 23, 109, 0.8);
    }

    blockquote {
      margin: 0;
    }
    main {
      min-width: 650px;
      width: 100vw;
      height: 100%;
      display: flex;
      justify-content: space-evenly;
    }
    #myTopo {
      display: none;
      flex: 1;
    }
    .custom-menu {
      position: absolute;
      border: 0 !important;
      border-radius: 5px;
      width: 180px;
      height: 200px;
      padding: 10px;
      box-shadow: 0 1px 4px #a5b7ff !important;
      background-color: rgba(46, 54, 56, 0.85) !important;
      color: white !important;
      display: none;
      z-index: 999;
    }

    .custom-menu a {
      display: inline-block;
      width: 100%;
      height: 30px;
      line-height: 30px;
      margin-bottom: 5px;
    }

    .custom-menu a:hover, .custom-menu a:active {
      cursor: pointer;
      color: orange;
    }

  </style>
  <link rel="stylesheet" href="../../../subassembly/visJs/vis.min.css">
  <link rel="stylesheet" href="../../../subassembly/visJs/vis-reset.css">
  <link rel="stylesheet" href="../../../../css/animate/animate.css">
  <link href="../../../subassembly/layui/css/layui.css" rel="stylesheet">
  <script src="../../../subassembly/common/jquery-3.5.1.min.js"></script>
  <script src="../../../subassembly/layui/layui.js"></script>
  <script src="../../../subassembly/visJs/vis.min.js"></script>
  <script src="../../../subassembly/common/common.js" type="text/javascript"></script>
  <script src="../../../subassembly/common/underscore-min.js" type="text/javascript"></script>
</head>
<body>
<header>
  <div class="titleContainer">
    <embed src="../../../../img/page-svg/third-line.svg"
           style="position: absolute;left: 0; top: 0; width: 100%; height: 100%"/>
    <p><span class="title">CRM系统-影响分析</span></p>
  </div>
</header>
<main>
  <div id="myTopo"></div>
</main>
<article class="custom-menu">
  <a data-type="detail" class="queryMyDetail">资源查看</a>
  <a data-type="mergeOrUnfold">关系展开/收缩</a>
  <a data-type="next">查看子资源</a>
</article>
<script>
  // 入参指定查看资源关联关系
  var cmdbId = _common_method.getUrlParam("cmdbId");
  var modelId = _common_method.getUrlParam("modelId");
  // 对应省份，默认江西电信
  var province = _common_method.getUrlParam("province");
  var defaultModel = "e69cd264485e4fdba69446f9c6757988";
  //所有的模型数据
  var allModelList = [];
  // 有监控的模型
  var monitorList = [];
  // 模型汇总分布
  var totalList = [];
  var monitor = cmdbId ? false : true;
  var isShowTitle = cmdbId ? false : true;
  var currentNodesData = [];

  var network = null;
  var nodesConfig = null;
  var edgesConfig = null;

  // 当前的所有节点
  var defaultAllTopo = [];
  // 当前拓扑图的索引下标
  var currentTopoIndex = 0;
  // 模块化声明
  var topoInvoke = function () {
    function invokeTopoData(id, resources) {
      layui.use('layer', function () {
        layer.load(1, {
          offset: ['50%', "50%"],
          shade: [0.8, '#393D49'] //0.1透明度的白色背景
        });
      });
      if (!(resources instanceof Array)) {
        var tmp = [];
        tmp.push(resources);
        resources = tmp;
      }
      var data = {
        id: id,
        type: resources
      };
      // resources = "default";
      var modelIds = null;
      if (resources == "default") {
        modelIds = defaultModel;
        //业务系统
        if (defaultModel instanceof Array) {
          modelIds = defaultModel;
        } else if (defaultModel) {
          modelIds = [];
          modelIds.push(defaultModel);
        } else {
          modelIds = [];
          modelIds.push("e69cd264485e4fdba69446f9c6757988");
        }
        data.type = modelIds;
      }
      //  var url = SERVICE.WSG_RESOURCE_MANAGE + "/resourceTopoManage/initWholeNetworkTopo";
      //var url = "http://127.0.0.1:8888/topo/query/relation";
      var url = SERVICE.WSG_GRAPH + "/topo/query/relation";
      var isTimeOut = $.ajax({
        url: url,
        type: "POST",
        data: JSON.stringify(data),
        dataType: "json",
        timeout: 65000,
        contentType: 'application/json',
        success: function (res) {
          if ((res.code == 1 || res.success) && (res.result || res.data)) {
            cmdbId = id;
            modelId = resources instanceof Array ? resources[0] : resources;
            nodesConfig.clear();
            edgesConfig.clear();
            var nodes = [];
            nodes = res.success ? res.result.nodes : res.data.nodes;
            var edges = res.success ? res.result.edges : res.data.edges;
            nodesConfig.add(nodes);
            edgesConfig.add(edges);

            currentNodesData = nodes;
            if (id) {
              window.setTimeout(function () {
                toNodeFocus(id, "white");
              }, 1500);
              var isMonitor = false;
              monitorList.forEach(function (item) {
                if (item.id == data.type[0]) {
                  isMonitor = true;
                }
              })
              if ($("input[id='openTab1']").is(":checked")) {
                $("input[name='tab']:checked").trigger('change');
              } else {
                $("input[id='openTab1']").click();
              }
              if (isMonitor) {
                $("#tab3").show();
                $("#tab4").show();
                $("#tab5").show();
              } else {
                $("#tab3").hide();
                $("#tab4").hide();
                $("#tab5").hide();
              }
              // $("input[name='tab']:checked").trigger('change');
            } else {
              cmdbId = null;
              $("input[id='openTab1']").click();
              $("#tab3").hide();
              $("#tab4").hide();
              $("#tab5").hide();
              window.setTimeout(function () {
                network.fit({
                  animation: {
                    offset: {x: 300, y: 300},
                    duration: 1000,
                    easingFunction: "easeInQuad",
                  }
                });
              }, 4500);
            }
          } else {
            layui.use('layer', function () {
              var layer = layui.layer;
              layer.msg(res.msg, {
                shade: 0.4,
                shadeClose: true, //开启遮罩关闭
                time: false,
              });
            });
            currentNodesData = [];
          }

          layui.use('layer', function () {
            layer.closeAll('loading'); //关闭加载层
          });
        },
        error: function (res) {
          layui.use('layer', function () {
            layer.closeAll('loading'); //关闭加载层
          });
          layui.use('layer', function () {
            var layer = layui.layer;
            layer.msg("列表加载失败", {
              shade: 0.4,
              shadeClose: true, //开启遮罩关闭
              time: false,
            });
          });
        },
        complete: function (res, status) {
          if (status === 'timeout') {//超时,status还有success,error等值的情况
            layui.use('layer', function () {
              layer.closeAll('loading'); //关闭加载层
            });
            isTimeOut.abort();
          }
        }
      });
    }

    function initTotalData(totalList) {

    }

    function toNodeFocus(id, style) {
      var allNodes = nodesConfig.get();
      allNodes.forEach(function (item) {
        var color = "#75AFFF";
        var size = 14;
        if (item.id == id) {
          color = style ? style : "#f33768";
          size = 20;
        }
        nodesConfig.update({id: item.id, font: {size: size, color: color}});
      });
      network.focus(id, {
        font: {
          /*全局设置拓扑图字体*/
          color: '#ffffff',
        },
        scale: 1.5,
        animation: {
          duration: 1000,
          easingFunction: "linear"
        },
      });
    }

    function getNextNodeAndEdge(m, currentSelectNode, filterList) {
      if (m.has(currentSelectNode)) {
        var list = m.get(currentSelectNode);
        for (var j = 0; j < list.length; j++) {
          filterList.push(list[j]);
          getNextNodeAndEdge(m, list[j].to, filterList);
        }
      }
    }

    function mergeOrUnfold(id) {
      var currentNode = nodesConfig.get(id);
      var isHide = false;
      if (currentNode.subHide) {
        isHide = true;
      }
      // 当前关联的线条（不包含隐藏的）
      var m = new Map();
      var edgeItems = edgesConfig.get();
      edgeItems.forEach(function (item) {
        // 有键值
        if (m.has(item.from)) {
          var l = m.get(item.from);
          l.push(item);
          m.set(item.from, l);
        } else {
          var a = [];
          a.push(item);
          m.set(item.from, a);
        }
      });
      var filterList = [];
      getNextNodeAndEdge(m, id, filterList);
      var filterNodes = [];
      var filterEdges = [];
      filterList.forEach(function (item) {
        if (!filterNodes.includes(item.to)) {
          filterNodes.push(item.to);
        }
        if (!filterEdges.includes(item.id)) {
          filterEdges.push(item.id);
        }
      });
      filterNodes.forEach(function (item) {
        nodesConfig.update({id: item, hidden: !isHide, subHide: !isHide});
      });
      nodesConfig.update({id: id, subHide: !isHide});
      filterEdges.forEach(function (item) {
        edgesConfig.update({id: item, hidden: !isHide, subHide: !isHide});
      });
    }

    function changeBackground(change) {
      var bg = localStorage.getItem("background-index");
      if (change) {
        if (bg == 0) {
          bg++;
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-1.jpg)");
          localStorage.setItem("background-index", bg);
        } else if (bg == 1) {
          bg++;
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-default.jpg)");
          localStorage.setItem("background-index", bg);
        } else if (bg == 2) {
          bg++;
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-3.jpg)");
          localStorage.setItem("background-index", bg);
        } else if (bg == 3) {
          bg = 0;
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-2.jpg)");
          localStorage.setItem("background-index", bg);
        } else {
          bg = 0;
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-2.jpg)");
          localStorage.setItem("background-index", bg);
        }
      } else {
        if (bg == 1) {
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-1.jpg)");
        } else if (bg == 2) {
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-default.jpg)");
        } else if (bg == 3) {
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-3.jpg)");
        } else {
          $("body").css("background", "url(../../../../../nresource/cmdb/images/topo/bg-2.jpg)");
          localStorage.setItem("background-index", 0);
        }
      }
    }

    var d = {};
    d.initTotalData = initTotalData;
    d.invokeTopoData = invokeTopoData;
    d.getNextNodeAndEdge = getNextNodeAndEdge;
    d.toNodeFocus = toNodeFocus;
    d.mergeOrUnfold = mergeOrUnfold;
    d.changeBackground = changeBackground;
    return d;
  }();

  $(document).ready(function () {
    if (isShowTitle) {
      $("header").show();
    }
    topoInvoke.changeBackground();
    nodesConfig = new vis.DataSet();
    edgesConfig = new vis.DataSet();
    draw();
    window.setTimeout(function () {
      if (monitor) {
        $(".monitorContainer").show();
        $(".tabShow").show();
        $(".queryMyDetail").show();
      } else {
        $(".monitorContainer").hide();
        $(".tabShow").hide();
        $(".queryMyDetail").hide();
      }
    }, 10);
  });

  function destroy() {
    if (network !== null) {
      network.destroy();
      network = null;
    }
  }

  function draw() {
    destroy();
    // create a network
    var container = document.getElementById("myTopo");
    var data = {
      nodes: nodesConfig,
      edges: edgesConfig,
    };
    var options = {
      locale: 'cn',
      interaction: {
        // 启用操作按钮
        navigationButtons: true,
        keyboard: true,
        /*启用鼠标聚焦事件*/
        hover: true
      },
      // 不启用节点操作
      manipulation: {
        enabled: false,
        initiallyActive: true,
        addNode: false,
        addEdge: false,
        editEdge: false,
        deleteNode: false,
        deleteEdge: false,
        controlNodeStyle: {}
      },
      physics: {
        enabled: true,
        stabilization: false,
        barnesHut: {
          gravitationalConstant: -8000
        },
        repulsion: {
          nodeDistance: 100, //(默认100，排斥的影响范围)
        }
      },
      nodes: {
        /*节点字体位置*/
        shape: "dot",
        /*缩小到一定程度才能查看字体*/
        /*节点(图标)大小*/
        size: 14,
        font: {
          /*全局设置拓扑图字体*/
          color: '#75AFFF',
          face: 'arial',
        }
      },
      edges: {
        /*全局设置箭头风格*/
        arrows: {
          to: {enabled: true, scaleFactor: 0.5, type: 'arrow'},
        },
        font: {
          color: '#a0baff',
          size: 0, // px
        },
        color: {color: "#0ca361", opacity: 0.68},
        shadow: false,
        /*全局设置线条虚线风格*/
        dashes: false,
        labelHighlightBold: false,
        arrowStrikethrough: false,//关系线与节点处无缝隙
      }
    };
    network = new vis.Network(container, data, options);

    network.on("hoverEdge", function (e) {
      this.body.data.edges.update({
        id: e.edge,
        font: {
          size: 12,
        },
      });
    });

    network.on("blurEdge", function (e) {
      this.body.data.edges.update({
        id: e.edge,
        font: {
          size: 0,
        },
      });
    });


    /**
     * TODO 单击事件
     */
    network.on("click", function (params) {
      if (!params.nodes || params.nodes.length == 0) {
        $(".custom-menu").hide();
        return;
      }
      var id = params.nodes[0];
      if (!id) {
        return;
      }
    });

    /**
     * TODO 双击事件
     */
    network.on("doubleClick", function (params) {
      if (!params.nodes || params.nodes.length == 0) {
        return;
      }
      // var id = params.nodes[0];
      // console.log(id);
      // 聚焦到某个节点，节点多的时候非常方便
      console.log("双击：" + params.nodes)
      topoInvoke.toNodeFocus(params.nodes)
      var node = nodesConfig.get(params.nodes);
      var currentModelId = node.type ? node.type : currentModelId = node[0].type;
      modelId = currentModelId;
      cmdbId = params.nodes instanceof Array ? params.nodes[0] : params.nodes;
      // queryResourcesBaseMsg(currentModelId, params.nodes);
      var isMonitor = false;
      monitorList.forEach(function (item) {
        if (item.id == currentModelId) {
          isMonitor = true;
        }
      });
      if (isMonitor) {
        $("#tab3").show();
        $("#tab4").show();
        $("#tab5").show();
      } else {
        $("#tab3").hide();
        $("#tab4").hide();
        $("#tab5").hide();
      }
      if ($("input[id='openTab1']").is(":checked")) {
        $("input[name='tab']:checked").trigger('change');
      } else {
        $("input[id='openTab1']").click();
      }
    });

    network.on("selectNode", function (params) {
      if (params.nodes.length == 1) {
        if (network.isCluster(params.nodes[0]) == true) {
          network.openCluster(params.nodes[0]);
        }
      }
    });
    // 单击鼠标右键触发
    network.on("oncontext", function (params) {
      var nodeId = this.getNodeAt(params.pointer.DOM);
      var defaultWith = 305;
      if ($(".resourcesFilter").is(':hidden')) {
        defaultWith = 5;
      }
      var defaultHight = -70;
      if (isShowTitle) {
        defaultHight = 0;
      }
      // 阻止冒泡
      params.event.preventDefault();
      if (nodeId) {
        var node = nodesConfig.get(nodeId);
        console.log(node.type);
        $(".custom-menu").data("resources", node.type);//100
        $(".custom-menu").data("id", nodeId);//100
        $(".custom-menu").data("isIncludeNext", node.isIncludeNext);
        $(".custom-menu").finish().toggle(100);
        $(".custom-menu").css({
          top: (params.pointer.DOM.y + defaultHight) + "px",
          left: (params.pointer.DOM.x + defaultWith) + "px"
        });
      } else {
        $(".custom-menu").hide();
      }
    });
  }

  //右键选中
  $("body").delegate('.custom-menu>a', 'click', function () {
    var id = $(this).parent().data("id");
    var resources = $(this).parent().data("resources");
    var type = $(this).data("type");
    var isIncludeNext = $(this).parent().data("isIncludeNext");
    console.log(id)
    if (!id) {
      $(".custom-menu").hide();
      return;
    }
    $(".custom-menu").hide();
    //$(".custom-menu").finish().toggle(50);
    if (type == "next") {
      if (isIncludeNext) {
        subResourcesOpen(id, resources);
      } else {
        layui.use('layer', function () {
          var layer = layui.layer;
          layer.msg("当前节点已无子节点,无法执行操作!", {
            shade: 0.4,
            shadeClose: true, //开启遮罩关闭
            time: false,
          });
        });
      }
    } else if (type == "mergeOrUnfold") {
      topoInvoke.mergeOrUnfold(id);
    } else if (type == 'detail') {
      var w = window.screen.availWidth * 0.8;
      var h = window.screen.availHeight * 0.8;
      var l = (screen.availWidth - w) / 2;
      var t = (screen.availHeight - h) / 2;
      var url = "/npage/cmdb/dynamic/detailOnlySee.html?opCode=&specId=" + resources + "&id=" + id;
      window.open(url, "_blank", "width=" + w + ",height=" + h + ",top=" + t + ",left=" + l + "," +
          "scrollbars=yes,resizable=1,location=no,modal=false,alwaysRaised=yes");
    } else if (type == 'history') {
      var w = window.screen.availWidth * 0.8;
      var h = window.screen.availHeight * 0.8;
      var l = (screen.availWidth - w) / 2;
      var t = (screen.availHeight - h) / 2;
      var url = "/npage/cmdb/topo/history.html?modelId=" + resources + "&id=" + id;
      window.open(url, "_blank", "width=" + w + ",height=" + h + ",top=" + t + ",left=" + l + "," +
          "scrollbars=yes,resizable=1,location=no,modal=false,alwaysRaised=yes");
    }
  });

  //关闭鼠标右键默认事件
  $(".custom-menu").bind("contextmenu", function () {
    return false;
  });


  function subResourcesOpen(id, resources) {
    topoInvoke.invokeTopoData(id, resources);
    var current = {id: id, type: resources};
    if (defaultAllTopo.length >= 10) {
      defaultAllTopo.pop();
    }
    defaultAllTopo.push(current);
    currentTopoIndex = defaultAllTopo.length - 1;
  }

</script>

</body>
</html>
